package com.lzc.loginauth.aspect;

import com.lzc.loginauth.annotation.LoginAuth;
import com.lzc.loginauth.constant.LoginConstant;
import com.lzc.loginauth.dataobject.AuthUser;
import com.lzc.loginauth.enums.AuthReturnType;
import com.lzc.loginauth.exception.HtmlException;
import com.lzc.loginauth.utils.ResultVOUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;

@Aspect
@Component
@Slf4j
public class LoginAuthAspect {

    @Around("execution(* com.lzc.loginauth.*.*.*(..))")
    public Object loginAuthAspect(ProceedingJoinPoint joinPoint) throws Throwable {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();

        Class<?> cls = joinPoint.getTarget().getClass();
        String methodName = joinPoint.getSignature().getName();

        boolean isLogin = isLogin(request);

        LoginAuth loginAuth;

        //  1.判断类上是否存在注解
        if (cls.isAnnotationPresent(LoginAuth.class)) {
            if (!isLogin) {
                log.info("【登录认证失败】");
                loginAuth = cls.getAnnotation(LoginAuth.class);
                // 判断返回类型
                if (loginAuth.authReturnType().getType().equals(AuthReturnType.JSON.getType())) {
                    return ResultVOUtil.error(1, "您还未登录，请先登录");
                } else {
                    throw new HtmlException("您还未登录，请先登录");
                }
            }
        } else {
            // 判断方法上是否存在注解
            for (Method method : cls.getDeclaredMethods()) {
                if (method.getName().equals(methodName) && method.isAnnotationPresent(LoginAuth.class)) {
                    if (!isLogin) {
                        log.info("【登录认证失败】");
                        loginAuth = method.getAnnotation(LoginAuth.class);
                        // 判断返回类型
                        if (loginAuth.authReturnType().getType().equals(AuthReturnType.JSON.getType())) {
                            return ResultVOUtil.error(1, "您还未登录，请先登录");
                        } else {
                            throw new HtmlException("您还未登录，请先登录");
                        }
                    }
                }
            }
        }
        return joinPoint.proceed();
    }

    private boolean isLogin(HttpServletRequest request) {
        HttpSession httpSession = request.getSession();
        AuthUser authUser = (AuthUser) httpSession.getAttribute(LoginConstant.AUTH_USER);
        if (authUser != null) {
            return true;
        }
        return false;
    }
}
